home *** CD-ROM | disk | FTP | other *** search
/ United Public Domain Gold 2 / United Public Domain Gold 2.iso / utilities / pu250.dms / pu250.adf / Graphics / VSprites / VSprites.doc < prev    next >
Text File  |  1992-05-02  |  29KB  |  1,022 lines

  1. 4    VSPRITES
  2.  
  3. 4.1  INTRODUCTION
  4.  
  5. VSprites, or Virtual Sprites as their whole name is, are very
  6. similar to Hardware Sprites. VSprites have the same limitations
  7. such as a maximum width of 16 pixels and can only use three
  8. colours (actually four colours, but the first colour will act
  9. as transparent.) However, VSprites are superior to Hardware
  10. Sprites because you may use much more than eight VSprites at
  11. the same time, and each VSprite may use its own three colours
  12. out of a palette of 4096 colours. The disadvantage with
  13. VSprites compared to Hardware Sprites is that Hardware Sprites
  14. are totally controlled by the hardware and thus very fast,
  15. while VSprites are partly controlled by the software and
  16. because of that a bit slower.
  17.  
  18.  
  19.  
  20. 4.2  HOW VSPRITES WORK
  21.  
  22. The reason why VSprites are so similar to Hardware Sprites is
  23. that VSprites are actually displayed with help of Hardware
  24. Sprites. If you want a VSprite to be at the top of the display
  25. and one further down, the system will position a Hardware Sprite
  26. at the top and change its image so it correspond to the
  27. VSprites image. The colours will also automatically be changed
  28. by altering the Copper List. (See chapter "Hacks" for more
  29. information about the Copper list.)
  30.  
  31. When the video beam has passed the first VSprite, the Hardware
  32. Sprite is not needed there any more and can therefore be used
  33. again. The system can therefore use the same Hardware Sprite to
  34. display another VSprite, and so on. Because of this you can have
  35. much more than eight sprites at the same time on the display.
  36.  
  37. If two or more VSprites would be on the same height, more
  38. Hardware Sprites are needed. The system has eight Hardware
  39. Sprites as its disposal, and can therefore display up to
  40. eight VSprites on the same line.
  41.  
  42. Here is an example. You want to display three VSprites
  43. positioned as below. In this case two Hardware Sprites are
  44. needed. Hardware Sprite one is used to display VSprite A
  45. and B. A and B are not on the same height, and only one
  46. Hardware Sprite is therefore needed. However, VSprite C
  47. is on the same lines as B, and a second Hardware Sprite is
  48. therefore needed.
  49.  
  50.   -----
  51.   | A |
  52.   -----
  53.     -----
  54.     | B |    -----
  55.     -----    | C |
  56.              -----
  57.  
  58.  
  59.  
  60. 4.2.1  LIMITATIONS
  61.  
  62. There are some important limitations that you need to remember:
  63.  
  64. 1. If you have reserved some Hardware Sprites for your own
  65.    use, the system can not use these sprites and this will
  66.    limit the maximum numbers of VSprites on the same height.
  67.  
  68. 2. Hardware Sprites 0 and 1, 2 and 3, 4 and 5, 6 and 7 share
  69.    the same colours. If sprite 0 is used to display one
  70.    VSprite, the computer can not use sprite 1 to display
  71.    another VSprite on the same height if it has different
  72.    colours. Because of that there is a limitation of a
  73.    maximum of four VSprites with different colours on the
  74.    same height.
  75.  
  76. 3. If you display the VSprites on a screen with a depth of 5
  77.    or more (32 colours or more) you will see strange colour
  78.    fluctuations on the lines where the VSprites are. The
  79.    reason is that VSprites are now using the same colour
  80.    register as the display, and as we said before, the system
  81.    is all the time changing these colours to match the
  82.    VSprites' colours.
  83.  
  84. If the system can not find a Hardware Sprite to display a
  85. VSprite because of the limitations above, the VSprite will
  86. simply not be drawn.
  87.  
  88.  
  89.  
  90. 4.2.2  HOW TO AVOID THE LIMITATIONS
  91.  
  92. There are several guidelines to follow in order to avoid the
  93. limitations:
  94.  
  95. 1. Use as few VSprites as possible on the same lines.
  96. 2. Try to use VSprites with the same colours.
  97. 3. If you are using a display with more than 16 colours, you
  98.    should only use colour 16, 20, 24, and 28. (These are the
  99.    transparent colours, and will therefore not be changed.)
  100.  
  101.  
  102.  
  103. 4.3  CREATE VSPRITES
  104.  
  105. IF YOU WANT TO USE VSPRITES YOU HAVE TO
  106. ---------------------------------------------------------------
  107.  1. Declare and initialize some sprite data for each VSprite.
  108.  2. Declare a VSprite structure for each VSprite plus two extra
  109.     structures for two dummy VSprites.
  110.  3. Decide each VSprite's colours.
  111.  4. Declare a GelsInfo structure.
  112.  5. Open the Graphics Library.
  113.  6. Initialize the GelsInfo structure.
  114.  7. Initialize the VSprite structure.
  115.  8. Add the VSprites to the VSprite list.
  116.  9. Sort the Gels list. SortGList()
  117. 10. Draw the Gels list. DrawGList()
  118. 11. Set the Copper and redraw the display.
  119.     [ MrgCop() and LoadView() or        ]
  120.     [ MakeScreen() and RethinkDisplay() ]    
  121. 12. Play around with the VSprites.
  122. 13. Remove the VSprites. RemVSprite()
  123.  
  124. (Easy, isn't it?)
  125.  
  126.  
  127.  
  128. 4.3.1  VSPRITE DATA
  129.  
  130. Sprite data for VSprites is declared and initialized as normal
  131. sprite data. Just remember that all sprite data must be placed
  132. in Chip memory.
  133.  
  134. Example:
  135.  
  136.   UWORD chip vsprite_data[]=
  137.   {
  138.     0x0FF0, 0x0FF0,
  139.     0x0FF0, 0x0FF0,
  140.     0x0FF0, 0x0FF0,
  141.     0x0FF0, 0x0FF0
  142.   };
  143.  
  144.  
  145.  
  146. 4.3.2  VSPRITE STRUCTURE
  147.  
  148. You need to declare a VSprite structure for each VSprite you
  149. are going to use, and two extra for two "dummy VSprites". The
  150. two dummy VSprites are used by the gel system (GEL stands for
  151. Graphic ELements). (One of the two dummy sprites is placed
  152. first in the gel-list, and the other one is placed last. The
  153. gel system can then sort the list much faster, and speed is
  154. essential here.)
  155.  
  156. Example:
  157.  
  158.   struct VSprite head, tail, vsprite;
  159.  
  160.  
  161. The VSprite structure looks like this: [Declared in the header
  162. file "graphics/gels.h".]
  163.  
  164. struct VSprite
  165. {
  166.   struct VSprite *NextVSprite;
  167.   struct VSprite *PrevVSprite;
  168.   struct VSprite *DrawPath;
  169.   struct VSprite *ClearPath;
  170.  
  171.   WORD OldY, OldX;
  172.   WORD Flags;
  173.   WORD Y, X;
  174.   WORD Height;
  175.   WORD Width;
  176.   WORD Depth;
  177.   WORD MeMask;
  178.   WORD HitMask;
  179.   WORD *ImageData;
  180.   WORD *BorderLine;
  181.   WORD *CollMask;
  182.   WORD *SprColors;
  183.   struct Bob *VSBob;
  184.   BYTE PlanePick;
  185.   BYTE PlaneOnOff;
  186.   VUserStuff VUserExt;
  187. };
  188.  
  189.  
  190. NextVSprite: Pointer to the next VSprite in the list.
  191.  
  192. PrevVSprite: Pointer to the previous VSprite in the list.
  193.  
  194. DrawPath:    Used by BOBs.
  195.  
  196. ClearPath:   Used by BOBs.
  197.  
  198. OldY:        Previous Y position.
  199.  
  200. OldX:        Previous X position.
  201.  
  202. Flags:       Following flags may be set by the user:
  203.                SUSERFLAGS Mask of the user settable flags.
  204.                VSPRITE    Set this flag if you are using the
  205.                           structure for a VSprite.
  206.                MUSTDRAW   Set this flag if this VSprite must
  207.                           be drawn.
  208.                           Following flags are set by the system:
  209.                GELGONE    This flag is set if the VSprite is
  210.                           outside the
  211.                VSOVERFLOW Too many VSprites on the same lines.
  212.                           If the flag MUSTDRAW is set, the
  213.                           system will try to draw it, but it
  214.                           could look strange.
  215.  
  216. Y:           Y position.
  217.  
  218. X:           X position.
  219.  
  220. Height:      The height of the VSprite.
  221.  
  222. Width:       Number of words used for each line. For the moment
  223.              a VSprite can only be 16 pixels wide, which means
  224.              two words. 
  225.  
  226. Depth:       Number of planes. A VSprite can for the moment
  227.              only use two planes, 3 colours and one transparent.
  228.  
  229. MeMask:      What can collide with this VSprite. (Will be
  230.              explained in a future version of the manual.)
  231.  
  232. HitMask:     What this VSprite can collide with. (Will be
  233.              explained in a future version of the manual.)
  234.  
  235. ImageData:   Pointer to the sprite data.
  236.  
  237. BorderLine:  (Will be explained in a future version of the manual.)
  238.  
  239.  
  240. CollMask:    (Will be explained in a future version of the manual.)
  241.  
  242. SprColors:   Pointer to a colour table for this VSprite.
  243.  
  244. VSBob:       Used if it is a BOB. (Will be explained in a future
  245.              version of the manual.)
  246.  
  247. PlanePick:   Used if it is a BOB. (Will be explained in a future
  248.              version of the manual.)
  249.  
  250. PlaneOnOff:  Used if it is a BOB. (Will be explained in a future
  251.              version of the manual.)
  252.  
  253. VUserExt:    You may use this as you please. Here you can add
  254.              extra information etc. (Is actually declared as a
  255.              SHORT variable.)
  256.  
  257.  
  258.  
  259. 4.3.3  COLOUR TABLE
  260.  
  261. Each VSprite can have its own three colours out of a palette
  262. of 4096. The three desired colours are placed in an array of
  263. WORDS.
  264.  
  265. Example:
  266.  
  267.   WORD colour_table[] = { 0x000F, 0x00F0, 0x0F00 };
  268.  
  269.  
  270.  
  271. 4.3.4  GELSINFO STRUCTURE
  272.  
  273. If you want to use VSprites or BOBs you have to declare and
  274. initialize a GelsInfo structure.
  275.  
  276. Example:
  277.  
  278.   struct GelsInfo ginfo;
  279.  
  280.  
  281. The GelsInfo structure looks like this: [Declared in the header
  282. file "graphics/rastport.h".]
  283.  
  284. struct GelsInfo
  285. {
  286.   BYTE sprRsrvd;
  287.   UBYTE Flags;
  288.   struct VSprite *gelHead, gelTail;
  289.   WORD *nextLine;
  290.   WORD **lastColor;
  291.   struct collTable *collHandler;
  292.   short leftmost, rightmost, topmost, bottommost;
  293.   APTR firstBlissObj, lastBlissObj;
  294. };
  295.  
  296. sprRsrvd:      Which hardware sprites should be reserved to
  297.                be used as VSprites. Bit zero represents the
  298.                first sprite, bit one the second sprite and so
  299.                on. If the bit is set, the sprite may be used.
  300.                Set the mask to 0xFF if all sprites should be
  301.                used as VSprites.
  302.  
  303. Flags:         Used by the system.
  304.  
  305. gelHead:       Pointer to the first dummy VSprite.
  306.  
  307. gelTail:       Pointer to the second dummy VSprite.
  308.  
  309. nextLine:      Which sprites are available on the next line.
  310.  
  311. lastColor:     Pointer to an array of colours which were last
  312.                used.
  313.  
  314. collHandler:   Pointer to the collision routines.
  315.  
  316. leftmost:      Used by the system.
  317.  
  318. rightmost:     Used by the system.
  319.  
  320. topmost:       Used by the system.
  321.  
  322. bottommost:    Used by the system.
  323.  
  324. firstBlissObj: Used by the system.
  325.  
  326. lastBlissObj:  Used by the system.
  327.  
  328.  
  329.  
  330. 4.3.5  INITIALIZE THE GELSINFO STRUCTURE
  331.  
  332. After you have declared the GelsInfo structure you need to
  333. initialize some important fields. First you need to tell the
  334. system which sprites it should be allowed to use as VSprites.
  335. If any hardware sprite should be allowed to be used, set the
  336. sprRsrvd field to 0xFF. If any sprite except the first two
  337. should be allowed to be used, set the mask to 0xFC.
  338.  
  339. You must also give the nextLine field a pointer to an array
  340. of eight WORDS, and the lastColor field a pointer to an array
  341. of eight WORD pointers. 
  342.  
  343. Example:
  344.  
  345.   WORD nextline[8];
  346.   WORD *lastcolor[8];
  347.  
  348.   /* All sprites except the first two may be used as VSprites: */
  349.   ginfo.sprRsrvd = 0xFC;
  350.  
  351.   ginfo.nextLine = nextline;
  352.   ginfo.lastColor = lastcolor;
  353.  
  354.  
  355. Finally you give the GelsInfo structure to the system by calling
  356. the InitGels() function, and give the Rastport's GelsInfo field
  357. a pointer to your GelsInfo structure.
  358.  
  359. Synopsis: InitGels( head, tail, ginfo );
  360.  
  361. head:     (struct VSprite *) Pointer to the first "dummy"
  362.           VSprite structure.
  363.  
  364. tail:     (struct VSprite *) Pointer to the second "dummy"
  365.           VSprite structure.
  366.  
  367. ginfo:    (struct GelsInfo *) Pointer to an initialized GelsInfo
  368.           structure.
  369.  
  370.  
  371. Example:
  372.  
  373.   /* Give the GelsInfo structure to the system: */
  374.   InitGels( &head, &tail, &ginfo );
  375.  
  376.   /* Give the Rastport a pointer to the GelsInfo structure: */
  377.   my_window->RPort->GelsInfo = &ginfo;
  378.  
  379.  
  380.  
  381. 4.3.6  INITIALIZE THE VSPRITE STRUCTURE
  382.  
  383. The VSprite structure must be initialized. You need to position
  384. the VSprite, set the height, width and depth. The width can for
  385. the moment only be 2 words wide (16 pixels), and have a depth of
  386. 2 (4 colours). You must also tell the structure that you want a
  387. VSprite. You do it by setting the Flags field to "VSPRITE".
  388. Finally you must give the structure a pointer to this VSprite's
  389. colour table and sprite data.
  390.  
  391. Example:
  392.  
  393. vsprite.X = x;                    /* Set the X and Y position.   */
  394. vsprite.Y = y;
  395. vsprite.Height = 16;              /* Set the height to 16 lines. */
  396. vsprite.Width = 2;                /* Set the width to 2 words.   */
  397. vsprite.Depth = 2;                /* Set the depth to 2 planes.  */
  398. vsprite.Flags = VSPRITE;          /* We want a VSprite.          */
  399. vsprite.SprColors = colour_table; /* Pointer to the colour table */
  400. vsprite.ImageData = vsprite_data; /* Pointer to the sprite data. */
  401.  
  402.  
  403.  
  404. 4.3.7  ADD THE VSPRITE TO THE VSPRITE LIST
  405.  
  406. When all structures are initialized we add the new VSprite to
  407. the list. We do it by calling the AddVSprite() function with
  408. a pointer to our VSprite structure and a pointer to the
  409. Rastport as parameters.
  410.  
  411. Synopsis: AddVSprite( vsprite, rp );
  412.  
  413. vsprite:  (struct VSprite *) Pointer to an initialized
  414.           VSprite structure.
  415.  
  416. rp:       (struct RastPort *) Pointer to the RastPort.
  417.  
  418.  
  419. Example:
  420.  
  421.   AddVSprite( &vsprite, my_window->RPort );
  422.  
  423.  
  424.  
  425. 4.3.8  PREPARE THE GEL SYSTEM
  426.  
  427. The last thing we have to do to see the new VSprite is to sort
  428. and draw the GEL list, change the copper list and finally
  429. redraw the screen. All this is done with help of four
  430. functions; SortGList(), DrawGList(), MrgCop() and LoadView().
  431.  
  432. If your program is running under Intuition you should use the
  433. functions MakeScreen() and RethinkDisplay() instead of MrgCop()
  434. and LoadView().
  435.  
  436.  
  437. SortGList() will reorganize the VSprite list so that the
  438. further down on the display the sprites are positioned the
  439. later they will appear in the list.
  440.  
  441. Synopsis: SortGList( rp );
  442.  
  443. rp:       (struct RastPort *) Pointer to the RastPort.
  444.  
  445.  
  446. DrawGList() will draw the VSprites into the specified Rastport.
  447.  
  448. Synopsis: DrawGList( rp, vp );
  449.  
  450. rp:       (struct RastPort *) Pointer to the RastPort.
  451.  
  452. vp:       (struct ViewPort *) Pointer to the ViewPort.
  453.  
  454.  
  455. MrgCop() reorganizes the Copper list. This is why each VSprite
  456. can have its own individual colour values.
  457.  
  458. Synopsis: MrgCop( view );
  459.  
  460. view:     (struct View *) Pointer to the View structure which
  461.           copper list should be changed.
  462.  
  463.  
  464. LoadView() will create and show the new display.
  465.  
  466. Synopsis: LoadView( view );
  467.  
  468. view:     (struct View *) Pointer to the View structure which
  469.           should be used to show the display.
  470.  
  471.  
  472. MakeScreen()
  473. Synopsis: MakeScreen( screen );
  474.  
  475. screen:   (struct Screen *) Pointer to the screen which
  476.           should be affected.
  477.  
  478.  
  479. RethinkDisplay() will reorganize the complete display. Note
  480. that this function will take quite a long time to execute,
  481. so use it only when absolutely needed.
  482.  
  483. Synopsis: RethinkDisplay();
  484.  
  485.  
  486. Example1: (You have created your own display.)
  487.  
  488.   SortGList( my_rastport );
  489.   DrawGList( my_rastport, my_viewport );
  490.   MrgCop( my_view );
  491.   LoadView( my_view );
  492.  
  493.  
  494. Example2: (Your program is running under Intuition.)
  495.  
  496.   SortGList( my_window->RPort );
  497.   DrawGList( my_window->RPort, &(my_screen->ViewPort) );
  498.   MakeScreen( my_screen );
  499.   RethinkDisplay();
  500.  
  501.  
  502.  
  503. 4.3.9  CHANGE THE VSPRITE
  504.  
  505. Once you have your VSprite you can start to play around with
  506. it. You can:
  507.  
  508. 1. Move it around by changing the X and Y fields in the VSprite
  509.    structure.
  510. 2. Change the image of the VSprite by giving the VSprite
  511.    structure a new pointer to another sprite data.
  512. 3. Change the VSprite colours by giving the VSprite structure
  513.    a new pointer to another colour table.
  514.  
  515. However, whatever you do with the VSprite you must always call
  516. the following functions to be able to see the changes:
  517.  
  518.   SortGList();
  519.   DrawGList();
  520.   MrgCop();
  521.   LoadView();
  522.  
  523. or
  524.  
  525.   SortGList();
  526.   DrawGList();
  527.   MakeScreen();
  528.   RethinkDisplay();
  529.  
  530.  
  531.  
  532. 4.3.10  REMOVE VSPRITES
  533.  
  534. When you want to remove a VSprite from the list you should call
  535. the RemVSprite() function.
  536.  
  537. Synopsis: RemVSprite( vsprite );
  538.  
  539. vsprite:  (struct VSprite *) Pointer to the VSprite you want
  540.           to remove.
  541.  
  542.  
  543. Example:
  544.  
  545.   RemVSprite( &vsprite );
  546.  
  547.  
  548.  
  549. 4.4  A COMPLETE EXAMPLE
  550.  
  551. Here is a complete example on how to use VSprites:
  552.  
  553. /* Example1                                                            */
  554. /* This example demonstrates how to get and use a VSprite. The VSprite */
  555. /* can be moved around by the user by pressing the arrow keys.         */
  556.  
  557.  
  558. /* Since we use Intuition, include this file: */
  559. #include <intuition/intuition.h>
  560.  
  561. /* Include this file since you are using sprites: */
  562. #include <graphics/gels.h>
  563.  
  564.  
  565. /* Declare the functions we are going to use: */
  566. void main();
  567. void clean_up();
  568.  
  569.  
  570. struct IntuitionBase *IntuitionBase = NULL;
  571. /* We need to open the Graphics library since we are using sprites: */
  572. struct GfxBase *GfxBase = NULL;
  573.  
  574.  
  575. /* Declare a pointer to a Screen structure: */ 
  576. struct Screen *my_screen;
  577.  
  578. /* Declare and initialize your NewScreen structure: */
  579. struct NewScreen my_new_screen=
  580. {
  581.   0,            /* LeftEdge  Should always be 0. */
  582.   0,            /* TopEdge   Top of the display.*/
  583.   640,          /* Width     We are using a high-resolution screen. */
  584.   200,          /* Height    Non-Interlaced NTSC (American) display. */
  585.   2,            /* Depth     4 colours. */
  586.   0,            /* DetailPen Text should be drawn with colour reg. 0 */
  587.   1,            /* BlockPen  Blocks should be drawn with colour reg. 1 */
  588.   HIRES|SPRITES,/* ViewModes High resolution, sprites will be used. */
  589.   CUSTOMSCREEN, /* Type      Your own customized screen. */
  590.   NULL,         /* Font      Default font. */
  591.   "VSprites!",  /* Title     The screen's title. */
  592.   NULL,         /* Gadget    Must for the moment be NULL. */
  593.   NULL          /* BitMap    No special CustomBitMap. */
  594. };
  595.  
  596.  
  597. /* Declare a pointer to a Window structure: */ 
  598. struct Window *my_window = NULL;
  599.  
  600. /* Declare and initialize your NewWindow structure: */
  601. struct NewWindow my_new_window=
  602. {
  603.   0,             /* LeftEdge    x position of the window. */
  604.   0,             /* TopEdge     y position of the window. */
  605.   640,           /* Width       640 pixels wide. */
  606.   200,           /* Height      200 lines high. */
  607.   0,             /* DetailPen   Text should be drawn with colour reg. 0 */
  608.   1,             /* BlockPen    Blocks should be drawn with colour reg. 1 */
  609.   CLOSEWINDOW|   /* IDCMPFlags  The window will give us a message if the */
  610.   RAWKEY,        /*             user has selected the Close window gad, */
  611.                  /*             or if the user has pressed a key. */
  612.   SMART_REFRESH| /* Flags       Intuition should refresh the window. */
  613.   WINDOWCLOSE|   /*             Close Gadget. */
  614.   WINDOWDRAG|    /*             Drag gadget. */
  615.   WINDOWDEPTH|   /*             Depth arrange Gadgets. */
  616.   WINDOWSIZING|  /*             Sizing Gadget. */
  617.   ACTIVATE,      /*             The window should be Active when opened. */
  618.   NULL,          /* FirstGadget No Custom gadgets. */
  619.   NULL,          /* CheckMark   Use Intuition's default CheckMark. */
  620.   "Use the arrow keys to move the VSprite!", /* Title */
  621.   NULL,          /* Screen      Will later be connected to a custom scr. */
  622.   NULL,          /* BitMap      No Custom BitMap. */
  623.   80,            /* MinWidth    We will not allow the window to become */
  624.   30,            /* MinHeight   smaller than 80 x 30, and not bigger */
  625.   640,           /* MaxWidth    than 640 x 200. */
  626.   200,           /* MaxHeight */
  627.   CUSTOMSCREEN   /* Type        Connected to the Workbench Screen. */
  628. };
  629.  
  630.  
  631. /* 1. Declare and initialize some sprite */
  632. /*    data for each VSprite:             */
  633. UWORD chip vsprite_data[]=
  634. {
  635.   0x0180, 0x0000,
  636.   0x03C0, 0x0000,
  637.   0x07E0, 0x0000,
  638.   0x0FF0, 0x0000,
  639.   0x1FF8, 0x0000,
  640.   0x3FFC, 0x0000,
  641.   0x7FFE, 0x0000,
  642.   0x0000, 0xFFFF,
  643.   0x0000, 0xFFFF,
  644.   0x7FFE, 0x7FFE,
  645.   0x3FFC, 0x3FFC,
  646.   0x1FF8, 0x1FF8,
  647.   0x0FF0, 0x0FF0,
  648.   0x07E0, 0x07E0,
  649.   0x03C0, 0x03C0,
  650.   0x0180, 0x0180,
  651. };
  652.  
  653.  
  654. /* 2. Declare three VSprite structures. One will be used, */
  655. /*    the other two are "dummies":                        */
  656. struct VSprite head, tail, vsprite;
  657.  
  658.  
  659. /* 3. Decide the VSprite's colours:            */
  660. /*                         RGB     RGB     RGB */
  661. WORD colour_table[] = { 0x000F, 0x00F0, 0x0F00 };
  662.  
  663.  
  664. /* 4. Declare a GelsInfo structure: */
  665. struct GelsInfo ginfo;
  666.  
  667.  
  668. /* This boolean variable will tell us if the VSprite is in */
  669. /* the list or not:                                        */
  670. BOOL vsprite_on = FALSE;
  671.  
  672.  
  673. /* This program will not open any console window if run from */
  674. /* Workbench, but we must therefore not print anything.      */
  675. /* Functions like printf() must therefore not be used.       */
  676. void _main()
  677. {
  678.  /* The GelsInfo structure needs the following arrays: */
  679.   WORD nextline[ 8 ];
  680.   WORD *lastcolor[ 8 ];
  681.  
  682.   /* Sprite position: */
  683.   WORD x = 40;
  684.   WORD y = 40;
  685.  
  686.   /* Direction of the sprite: */
  687.   WORD x_direction = 0;
  688.   WORD y_direction = 0;
  689.  
  690.   /* Boolean variable used for the while loop: */
  691.   BOOL close_me = FALSE;
  692.  
  693.   ULONG class; /* IDCMP */
  694.   USHORT code; /* Code */
  695.  
  696.   /* Declare a pointer to an IntuiMessage structure: */
  697.   struct IntuiMessage *my_message;
  698.  
  699.  
  700.   /* Open the Intuition Library: */
  701.   IntuitionBase = (struct IntuitionBase *)
  702.     OpenLibrary( "intuition.library", 0 );
  703.   
  704.   if( IntuitionBase == NULL )
  705.     clean_up(); /* Could NOT open the Intuition Library! */
  706.  
  707.  
  708.   /* 5. Open the Graphics Library:                                    */
  709.   /* Since we are using sprites we need to open the Graphics Library: */
  710.   /* Open the Graphics Library: */
  711.   GfxBase = (struct GfxBase *)
  712.     OpenLibrary( "graphics.library", 0);
  713.  
  714.   if( GfxBase == NULL )
  715.     clean_up(); /* Could NOT open the Graphics Library! */
  716.  
  717.  
  718.   /* We will now try to open the screen: */
  719.   my_screen = (struct Screen *) OpenScreen( &my_new_screen );
  720.  
  721.   /* Have we opened the screen succesfully? */
  722.   if(my_screen == NULL)
  723.     clean_up();
  724.  
  725.  
  726.   my_new_window.Screen = my_screen;
  727.  
  728.  
  729.   /* We will now try to open the window: */
  730.   my_window = (struct Window *) OpenWindow( &my_new_window );
  731.   
  732.   /* Have we opened the window succesfully? */
  733.   if(my_window == NULL)
  734.     clean_up(); /* Could NOT open the Window! */
  735.  
  736.  
  737.   /* 6. Initialize the GelsInfo structure: */
  738.  
  739.   /* All sprites except the first two may be used to draw */
  740.   /* the VSprites: ( 11111100 = 0xFC )                    */
  741.   ginfo.sprRsrvd = 0xFC;
  742.   /* If we do not exclude the first two sprites, the mouse */
  743.   /* pointer's colours may be affected.                    */
  744.  
  745.  
  746.   /* Give the GelsInfo structure some memory: */
  747.   ginfo.nextLine = nextline;
  748.   ginfo.lastColor = lastcolor;
  749.  
  750.  
  751.   /* Give the Rastport a pointer to the GelsInfo structure: */
  752.   my_window->RPort->GelsInfo = &ginfo;
  753.  
  754.   
  755.   /* Give the GelsInfo structure to the system: */
  756.   InitGels( &head, &tail, &ginfo );
  757.  
  758.  
  759.   /* 7. Initialize the VSprite structure: */
  760.  
  761.   vsprite.Flags = VSPRITE; /* It is a VSprite.            */
  762.   vsprite.X = x;           /* X position.                 */
  763.   vsprite.Y = y;           /* Y position.                 */
  764.   vsprite.Height = 16;     /* 16 lines tall.              */
  765.   vsprite.Width = 2;       /* Two bytes (16 pixels) wide. */
  766.   vsprite.Depth = 2;       /* Two bitplanes, 4 colours.   */
  767.  
  768.  
  769.   /* Pointer to the sprite data: */
  770.   vsprite.ImageData = vsprite_data;
  771.  
  772.   /* Pointer to the colour table: */
  773.   vsprite.SprColors = colour_table;
  774.  
  775.  
  776.   /* 8. Add the VSprites to the VSprite list: */
  777.   AddVSprite( &vsprite, my_window->RPort );
  778.  
  779.   /* The VSprite is in the list. */
  780.   vsprite_on = TRUE;
  781.   
  782.  
  783.   /* Stay in the while loop until the user has selected the Close window */
  784.   /* gadget: */
  785.   while( close_me == FALSE )
  786.   {
  787.     /* Stay in the while loop as long as we can collect messages */
  788.     /* successfully: */
  789.     while(my_message = (struct IntuiMessage *) GetMsg(my_window->UserPort))
  790.     {
  791.       /* After we have collected the message we can read it, and save any */
  792.       /* important values which we maybe want to check later: */
  793.       class = my_message->Class;
  794.       code  = my_message->Code;
  795.  
  796.       /* After we have read it we reply as fast as possible: */
  797.       /* REMEMBER! Do never try to read a message after you have replied! */
  798.       /* Some other process has maybe changed it. */
  799.       ReplyMsg( my_message );
  800.  
  801.       /* Check which IDCMP flag was sent: */
  802.       switch( class )
  803.       {
  804.         case CLOSEWINDOW:     /* Quit! */
  805.                close_me=TRUE;
  806.                break;  
  807.  
  808.         case RAWKEY:          /* A key was pressed! */
  809.                /* Check which key was pressed: */
  810.                switch( code )
  811.                {
  812.                  /* Up Arrow: */
  813.                  case 0x4C:      y_direction = -1; break; /* Pre */
  814.                  case 0x4C+0x80: y_direction = 0;  break; /* Rel */
  815.  
  816.                  /* Down Arrow: */
  817.                  case 0x4D:      y_direction = 1; break; /* Pre */
  818.                  case 0x4D+0x80: y_direction = 0; break; /* Rel */
  819.  
  820.                  /* Right Arrow: */
  821.                  case 0x4E:      x_direction = 2; break; /* Pre */
  822.                  case 0x4E+0x80: x_direction = 0; break; /* Rel */
  823.  
  824.                  /* Left Arrow: */
  825.                  case 0x4F:      x_direction = -2; break; /* Pre */
  826.                  case 0x4F+0x80: x_direction = 0;  break; /* Rel */
  827.                }
  828.                break;  
  829.       }
  830.     }
  831.  
  832.  
  833.     /* 12. Play around with the VSprite: */
  834.  
  835.     /* Change the x/y position: */
  836.     x += x_direction;
  837.     y += y_direction;
  838.  
  839.     /* Check that the sprite does not move outside the screen: */
  840.     if(x > 320)
  841.       x = 320;
  842.     if(x < 0)
  843.       x = 0;
  844.     if(y > 200)
  845.       y = 200;
  846.     if(y < 0)
  847.       y = 0;
  848.  
  849.     vsprite.X = x;
  850.     vsprite.Y = y;
  851.  
  852.  
  853.     /* 9. Sort the Gels list: */
  854.     SortGList( my_window->RPort );
  855.  
  856.     /* 10. Draw the Gels list: */
  857.     DrawGList( my_window->RPort, &(my_screen->ViewPort) );
  858.  
  859.     /* 11. Set the Copper and redraw the display: */
  860.     MakeScreen( my_screen );
  861.     RethinkDisplay();    
  862.   }
  863.  
  864.  
  865.   /* Free all allocated memory: (Close the window, libraries etc) */
  866.   clean_up();
  867.  
  868.   /* THE END */
  869. }
  870.  
  871.  
  872. /* This function frees all allocated memory. */
  873. void clean_up()
  874. {
  875.  /* 13. Remove the VSprites: */
  876.   if( vsprite_on )
  877.     RemVSprite( &vsprite );
  878.  
  879.   if( my_window )
  880.     CloseWindow( my_window );
  881.   
  882.   if(my_screen )
  883.     CloseScreen( my_screen );
  884.  
  885.   if( GfxBase )
  886.     CloseLibrary( GfxBase );
  887.  
  888.   if( IntuitionBase )
  889.     CloseLibrary( IntuitionBase );
  890.  
  891.   exit();
  892. }
  893.  
  894.  
  895.  
  896. 4.5  FUNCTIONS
  897.  
  898. InitGels()
  899.  
  900.   This function "gives" an already prepared GelsInfo structure
  901.   to the system.
  902.  
  903.   Synopsis: InitGels( head, tail, ginfo );
  904.  
  905.   head:     (struct VSprite *) Pointer to the first "dummy"
  906.             VSprite structure.
  907.  
  908.   tail:     (struct VSprite *) Pointer to the second "dummy"
  909.             VSprite structure.
  910.  
  911.   ginfo:    (struct GelsInfo *) Pointer to an initialized GelsInfo
  912.             structure.
  913.  
  914.  
  915. AddVSprite()
  916.  
  917.   This function will add a VSprite to the VSprite list.
  918.  
  919.   Synopsis: AddVSprite( vsprite, rp );
  920.  
  921.   vsprite:  (struct VSprite *) Pointer to an initialized
  922.             VSprite structure.
  923.  
  924.   rp:       (struct RastPort *) Pointer to the RastPort.
  925.  
  926.  
  927.  
  928. RemVSprite()
  929.   
  930.   This function will remove a previously added VSprite.
  931.  
  932.   Synopsis: RemVSprite( vsprite );
  933.  
  934.   vsprite:  (struct VSprite *) Pointer to the VSprite you want
  935.             to remove.
  936.  
  937.  
  938.  
  939. SortGList()
  940.  
  941.   This function will reorganize the VSprite list so that the
  942.   further down on the display the sprites are positioned the
  943.   later they will appear in the list.
  944.  
  945.   Synopsis: SortGList( rp );
  946.  
  947.   rp:       (struct RastPort *) Pointer to the RastPort.
  948.  
  949.  
  950. DrawGList()
  951.  
  952.   This function will draw the VSprites into the specified
  953.   Rastport.
  954.  
  955.   Synopsis: DrawGList( rp, vp );
  956.  
  957.   rp:       (struct RastPort *) Pointer to the RastPort.
  958.  
  959.   vp:       (struct ViewPort *) Pointer to the ViewPort.
  960.  
  961.  
  962. MrgCop()
  963.  
  964.   This function reorganizes the Copper list. This is why each
  965.   VSprite can have its own individual colour values.
  966.  
  967.   Synopsis: MrgCop( view );
  968.  
  969.   view:     (struct View *) Pointer to the View structure which
  970.             copper list should be changed.
  971.  
  972.  
  973. LoadView()
  974.  
  975.   This function will create and show the new display.
  976.  
  977.   Synopsis: LoadView( view );
  978.  
  979.   view:     (struct View *) Pointer to the View structure which
  980.             should be used to show the display.
  981.  
  982.  
  983. MakeScreen()
  984.  
  985.   This function will recalculate the screen display values. 
  986.  
  987.   Synopsis: MakeScreen( screen );
  988.  
  989.   screen:   (struct Screen *) Pointer to the screen which
  990.             should be affected.
  991.  
  992.  
  993. RethinkDisplay()
  994.  
  995.   This function will reorganize the complete display. Note
  996.   that this function will take quite a long time to execute,
  997.   so use it only when absolutely needed.
  998.  
  999.   Synopsis: RethinkDisplay();
  1000.  
  1001.  
  1002.  
  1003. 4.6  EXAMPLES
  1004.  
  1005. Example1
  1006.   This example demonstrates how to get and use a VSprite.
  1007.   The VSprite can be moved around by the user by pressing
  1008.   the arrow keys.
  1009.  
  1010. Example2
  1011.   This example demonstrates how to use several VSprites each
  1012.   with its own colour table.
  1013.  
  1014. Example3
  1015.   This program demonstrates how to animate several (!) VSprites.
  1016.  
  1017. Example4
  1018.   This example demonstrates how to use a VSpriteon a display
  1019.   you have created yourself. We must now use the low level
  1020.   functions MrgCop(), and LoadView(), instead of the more
  1021.   sophisticated functions MakeScreen(), RethinkDisplay().
  1022.